package me.spring.cloud.common.components.dlog.dynamic;

import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfig;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import java.util.Set;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * springcloud 动态日志配置.将log level存储于apollo,可在运行时动态修改日志级别. 业务方需要扫描到该路径
 */
public class CloudLogLevelConfig implements ApplicationContextAware {

  private static final Logger logger = LoggerFactory.getLogger(BootLogLevelConfig.class);
  private static final String LOGGER_TAG = "logging.level.";

  private ApplicationContext applicationContext;

  @ApolloConfig
  private Config config;

  @PostConstruct
  private void initialize() {
    if (null != config) {
      refreshLoggingLevels(config.getPropertyNames());
    }
  }

  @ApolloConfigChangeListener(interestedKeyPrefixes = {LOGGER_TAG})
  private void onChange(ConfigChangeEvent changeEvent) {
    this.refreshLoggingLevels(changeEvent.changedKeys());
  }

  private void refreshLoggingLevels(Set<String> changedKeys) {
    logger.info("Refreshing logging levels: {}", changedKeys);
    this.applicationContext.publishEvent(new EnvironmentChangeEvent(changedKeys));
    logger.info("LogProperties refreshed!");
  }


  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.applicationContext = applicationContext;
  }
}
